<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="next">执行增加</button>
    <button id="pre">撤销</button>
    <button id="redo">重做</button>
    <script>
        //自增
        function IncrementCommand() {
            // 当前值
            this.val = 0;
            // 命令栈
            this.stack = [];
            // 栈指针位置
            this.stackPosition = -1;
        };

        IncrementCommand.prototype = {
            construtor: IncrementCommand,

            //执行
            execute:function(){
                this._clearRedo();
                
                //定义执行的处理
                var command = function(){
                    this.val += 2;
                }.bind(this);

                //执行并缓存起来
                command();

                this.stack.push(command);

                this.stackPosition++;

                this.getValue();

            },
            canUndo:function(){
                return this.stackPosition >= 0
            },
            canRedo:function(){
                return this.stackPosition < this.stack.length -1;
            },

            //撤销
            undo:function() {
                if(!this.canUndo){
                    return;
                }

                this.stackPosition--;
                //命令的撤销，与执行的处理相反
                var command = function(){
                    this.val -= 2;
                }.bind(this);

                //撤销后不需要缓存
                command();
                
                this.getValue();
            },

            //重做
            redo: function() {
                if(!this.canRedo()){
                    return;
                }

                //执行栈顶的命令
                this.stack[++this.stackPosition]();
                this.getValue();
            },

            //在执行时,已经撤销的部分再重做
            _clearRedo:function(){
                this.stack = this.stack.slice(0,this.stackPosition+1)
            },

            //获取当前值
            getValue: function(){
                console.log(this.val);
            }
        }

        //再实例化进行测试，模拟执行、撤销、重做的操作

        var incrementCommand = new IncrementCommand();

        // 模拟事件触发，执行命令
        var eventTrigger = {
            // 某个事件的处理中，直接调用命令的处理方法
            increment: function(){
                incrementCommand.execute();
            },

            incrementUndo:function(){
                incrementCommand.undo();
            },

            incrementRedo: function(){
                incrementCommand.redo();
            }
        }

        // eventTrigger['increment'](); //2
        // eventTrigger['increment'](); //4

        // eventTrigger['incrementUndo'](); // 2

        // eventTrigger['increment'](); // 4
        var next = document.getElementById('next')
        var pre = document.getElementById('pre')
        var redo = document.getElementById('redo')
        console.log(next)
        next.onclick=function(){
            eventTrigger['increment']()
        }
        pre.onclick = function(){
            eventTrigger['incrementUndo']()
        }
        redo.onclick = function(){
            eventTrigger['incrementRedo']()
        }

    </script>
</body>
</html>